<template>
  <div class="form-phone" ref="phoneRef">
    <div class="tx-btn text-blue-dark mb-1">{{ title }}</div>
    <div
      class="form-phone-wrapper"
      :class="[
        { 'is-number-focus': isFocusNumber },
        { 'is-code-focus': isListOpen },
        { 'has-error': myError.length > 0 },
      ]"
    >
      <div class="form-select" @click="isListOpen = !isListOpen">
        <input
          type="text"
          class="form-select-btn"
          :class="[
            { 'is-number-focus': isFocusNumber },
            { 'is-code-focus': isListOpen },
            { 'has-error': myError.length > 0 },
          ]"
          v-model="myCode"
          readonly
        />
      </div>
      <div class="form-number" @click="isListOpen = false">
        <input
          :class="[
            { 'is-number-focus': isFocusNumber },
            { 'is-code-focus': isListOpen },
            { 'has-error': myError.length > 0 },
          ]"
          type="text"
          v-model="myNumberValue"
          placeholder="12345678"
          @change="checkError"
          @focus="isFocusNumber = true"
          @blur="isFocusNumber = false"
        />
      </div>
      <div
        class="form-phone-select-menu"
        :class="[{ 'is-active': isListOpen }]"
      >
        <ScrollBar>
          <ul
            class="form-select-list"
            @click="isListOpen = !isListOpen"
          >
            <li
              class="form-select-option flex-between"
              v-for="item in options"
              :key="item.key"
              @click="myCode = item.value"
            >
              <div class="option-label text-teal">
                {{ item.label }}
              </div>
              <div class="option-name text-black">
                {{ item.name }}
              </div>
            </li>
          </ul>
        </ScrollBar>
      </div>
    </div>
    <div class="input-error" v-if="myNumberValue">
      请输入正确的格式
    </div>
    <div class="input-error" v-else>
      {{ error.errorMsg }}
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, nextTick, onMounted, onBeforeUnmount } from 'vue';
import ScrollBar from "@/common/ScrollBar/index.vue";
import http from "@/utils/http";

defineOptions({
  name: "FormPhone"
});

interface CountryItem {
  dial_code: string;
  country: string;
  key: string;
  label: string;
  value: string;
  name: string;
}

interface PhoneValue {
  code?: string;
  number?: string;
}

interface ErrorObject {
  errorMsg?: string;
}

interface Props {
  value?: PhoneValue;
  title?: string;
  error?: ErrorObject;
  optional?: boolean;
  componentKey?: string;
  website?: string;
  locale?: string;
}

const props = withDefaults(defineProps<Props>(), {
  value: () => ({}),
  title: "",
  error: () => ({}),
  optional: false,
  componentKey: "",
  website: "",
  locale: ""
});

interface Emits {
  (e: 'updateValue', value: PhoneValue): void;
  (e: 'updateError', data: { key: string; isPass: boolean }): void;
}

const emit = defineEmits<Emits>();

const isListOpen = ref(false);
const isFocusNumber = ref(false);
const myError = ref<string[]>([]);
const country = ref<CountryItem[]>([]);
const phoneRef = ref(null);

const options = computed(() => {
  return country.value;
});

const myCode = computed({
  get() {
    return props.value?.code ?? "";
  },
  set(nVal: string) {
    emit("updateValue", {
      code: nVal,
      number: myNumberValue.value ?? "",
    });
  },
});

const myNumberValue = computed({
  get() {
    return props.value?.number ?? "";
  },
  set(nVal: string) {
    emit("updateValue", {
      code: myCode.value,
      number: nVal,
    });
  },
});

const validatePhone = (phone: string) => { 
  // 允许的字符：数字、空格、括号、连字符、加号
  const phoneRegex = /^[\d\s\-\(\)]+$/;
  return phoneRegex.test(phone) && phone.replace(/\D/g, '').length >= 7;
};

const checkError = () => {
  if (props.optional) return;
  const key = "myNumber";
  nextTick(() => {
    const isValid = validatePhone(myNumberValue.value);
    console.log('isValid', isValid)
    const numberValue = myNumberValue.value;
    console.log('numberValue', numberValue)
    if ((!numberValue || !isValid) && myError.value.indexOf(key) < 0)
      myError.value.push(key);
    if (numberValue && isValid && myError.value.indexOf(key) > -1)
      myError.value.splice(myError.value.indexOf(key), 1);

    emit("updateError", {
      key: props.componentKey,
      isPass: myError.value.length <= 0,
    });
  });
};

const getCountry = async () => {
  try {
    const config = {
      headers: {
        website: `${props.website}-${props.locale}`,
      },
    };
    const url = `country`;
    const { data } = await http.get(url, config);
    country.value = data.data.map((v: CountryItem) => {
      return {
        ...v,
        key: v.dial_code,
        label: v.country,
        value: v.dial_code,
        name: `+${v.dial_code}`,
      };
    });
    if (!myCode.value && country.value.length > 0) {
      myCode.value = country.value[0].value;
    }
  } catch (error) {
    console.error('Failed to fetch country data:', error);
  }
};

// 点击外部关闭下拉菜单
const handleClickOutside = (event: MouseEvent) => {
  if (phoneRef.value && !(phoneRef.value as HTMLElement).contains(event.target as Node)) {
    isListOpen.value = false;
  }
};

onMounted(() => {
  getCountry();

  // 添加全局点击事件监听
  document.addEventListener('click', handleClickOutside);
});

onBeforeUnmount(() => {
  // 移除全局点击事件监听
  document.removeEventListener('click', handleClickOutside);
});
</script>

<style lang="scss" scoped>
.tx-body-p {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.75
}

@media(max-width: 1023.98px) {
  .tx-body-p {
      font-size:14px;
      line-height: 1.714;
      letter-spacing: .01em
  }
}

.tx-body {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: .01em
}

@media(max-width: 1023.98px) {
  .tx-body {
      font-size:14px;
      line-height: 1.285;
      letter-spacing: .01em
  }
}

.tx-btn {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.285;
  letter-spacing: .04em
}

@media(max-width: 1023.98px) {
  .tx-btn {
      line-height:1.428
  }
}

@media(max-width: 767.98px) {
  .tx-btn {
      line-height:1.285
  }
}

.text-blue-dark {
  --bs-text-opacity: 1;
  color: rgba(0,50,160,var(--bs-text-opacity))!important;
}

.mb-1 {
  margin-bottom: 4px!important
}

.form-phone {
  margin-bottom: 36px;
}

@media (max-width: 767.98px) {
  .form-phone {
    margin-bottom: 24px;
  }
}

.form-phone-wrapper {
  position: relative;
  display: flex;
  border-radius: 4px;
  background: #F7F7FA;
  transition: margin-bottom .3s ease-in-out;
}

@media (max-width: 767.98px) {
  .form-phone-wrapper {
    background: rgba(255,255,255,1);
  }
}

.form-phone-wrapper.is-number-focus {
  border: 1px solid #0048E8;
}

.form-phone-wrapper.is-code-focus {
  background: rgba(255,255,255,1);
  margin-bottom: 120px;
}

@media (max-width: 767.98px) {
  .form-phone-wrapper.is-code-focus {
    background: #F7F7FA;
  }
}

.form-phone-wrapper.has-error {
  border: 2px solid #FF0044;

  & + .input-error {
    opacity: 1;
  }
}

.form-phone .input-error {
  position: absolute;
  margin-top: 4px;
  color: #CE031A;
  opacity: 0;
  transition: opacity .15s ease-in-out;
  pointer-events: none;
}

.form-phone .form-select {
  position: relative;
  width: 60px;
  flex-shrink: 0;
}

.form-phone .form-select::after {
  content: '';
  position: absolute;
  right: 4px;
  top: 50%;
  width: 14px;
  height: 14px;
  background: url() 50% no-repeat;
  background-size: 100% auto;
  transform: translateY(-50%) rotateZ(90deg);
  transition: transform .3s ease-in-out;
}

.form-phone .form-select {
  cursor: pointer;
}

.form-phone .form-select-btn {
  @extend .tx-body-p;
  color: #1A1C20;
  background: none;
  background: #F7F7FA;
  border-radius: 4px;
  border: none;
  padding: 0;
  padding: 10px 6px 10px 14px;
  outline: none;
  width: 100%;
  cursor: pointer;
}

@media (max-width: 767.98px) {
  .form-phone .form-select-btn {
    background: rgba(255,255,255,1);
  }
}

.form-phone .form-select-btn::placeholder {
  @extend .tx-body-p;
  color: #C0C0C4;
}

.form-phone .form-select-btn.is-number-focus {
  padding: 9px 6px 9px 13px;
}

.form-phone .form-select-btn.has-error {
  padding: 8px 6px 8px 12px;
}

.form-phone .form-number {
  margin-left: 3px;
  width: 100%;
}

.form-phone .form-number input {
  @extend .tx-body-p;
  color: #1A1C20;
  background: none;
  background: #F7F7FA;
  border-radius: 4px;
  border: none;
  padding: 10px 14px;
  width: 100%;
  outline: none;
}

@media (max-width: 767.98px) {
  .form-phone .form-number input {
    background: rgba(255,255,255,1);
  }
}


.form-phone .form-number input::placeholder {
  @extend .tx-body-p;
  color: #C0C0C4;
}

.form-phone .form-number input.is-code-focus {
  background: rgba(255,255,255,1);
  color: #C0C0C4;
}

@media (max-width: 767.98px) {
  .form-phone .form-number input.is-code-focus {
    background: #F7F7FA;
  }
}

.form-phone .form-number input.is-number-focus {
  padding: 9px 13px;
}

.form-phone .form-number input.has-error {
  padding: 8px 12px;
}

.form-phone-select-menu {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 48px;
  width: 100%;
  transform: translateY(-20px);
  opacity: 0;
  pointer-events: none;
  transition: transform .3s ease-in-out, opacity .3s ease-in-out;
}

.form-phone-select-menu > .scroll-bar ::v-deep .simple-bar {
  max-height: 144px;
}

.form-phone-select-menu.is-active {
  transform: translateY(0);
  opacity: 1;
  pointer-events: visible;
}

.form-phone .form-select-list {
  border-radius: 4px;
  background: #F7F7FA;
}

@media (max-width: 767.98px) {
  .form-phone .form-select-list {
    background: rgba(255,255,255,1);
  }
}

.form-phone .form-select-option {
  padding: 8px 18px 8px 12px;
  @extend .tx-body;
  color: #000;
  cursor: pointer;
}

.form-phone .form-select-option:not(:first-child) {
  border-top: 1px solid rgba(255,255,255,1);
}

@media (max-width: 767.98px) {
  .form-phone .form-select-option:not(:first-child) {
    border-top: 1px solid #F7F7FA;
  }
}

.form-phone .option-label {
  font-size: 14px;
  line-height: 16px;
}

.form-phone .option-name {
  font-size: 14px;
  line-height: 20px;
}  
</style>